﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using SAPbouiCOM;
using EventMenuKeyTuple = System.Tuple<string, SAPbouiCOM.BoEventTypes, bool>;

namespace SapFramework.Interface.Events.EventCollections
{
    public class MenuEventDictionary : Dictionary<EventMenuKeyTuple,MethodInfo>
    {
        #region Construtores - Passados para internal para que não se possam criar instâncias desta classe fora desta DLL (em especial, da classe EventListener)

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class that is empty, has the default initial capacity, and uses the default equality comparer for the key type.
        /// </summary>
        internal MenuEventDictionary() { }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class that is empty, has the specified initial capacity, and uses the default equality comparer for the key type.
        /// </summary>
        /// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Generic.Dictionary`2"/> can contain.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>
        internal MenuEventDictionary( int capacity ) : base( capacity ) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class that is empty, has the default initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer`1"/>.
        /// </summary>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> implementation to use when comparing keys, or null to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1"/> for the type of the key.</param>
        internal MenuEventDictionary( IEqualityComparer<EventMenuKeyTuple> comparer ) : base( comparer ) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class that is empty, has the specified initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer`1"/>.
        /// </summary>
        /// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Generic.Dictionary`2"/> can contain.</param><param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> implementation to use when comparing keys, or null to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1"/> for the type of the key.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>
        internal MenuEventDictionary( int capacity, IEqualityComparer<EventMenuKeyTuple> comparer ) : base( capacity, comparer ) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class that contains elements copied from the specified <see cref="T:System.Collections.Generic.IDictionary`2"/> and uses the default equality comparer for the key type.
        /// </summary>
        /// <param name="dictionary">The <see cref="T:System.Collections.Generic.IDictionary`2"/> whose elements are copied to the new <see cref="T:System.Collections.Generic.Dictionary`2"/>.</param><exception cref="T:System.ArgumentNullException"><paramref name="dictionary"/> is null.</exception><exception cref="T:System.ArgumentException"><paramref name="dictionary"/> contains one or more duplicate keys.</exception>
        internal MenuEventDictionary( IDictionary<EventMenuKeyTuple, MethodInfo> dictionary ) : base( dictionary ) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class that contains elements copied from the specified <see cref="T:System.Collections.Generic.IDictionary`2"/> and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer`1"/>.
        /// </summary>
        /// <param name="dictionary">The <see cref="T:System.Collections.Generic.IDictionary`2"/> whose elements are copied to the new <see cref="T:System.Collections.Generic.Dictionary`2"/>.</param><param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> implementation to use when comparing keys, or null to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1"/> for the type of the key.</param><exception cref="T:System.ArgumentNullException"><paramref name="dictionary"/> is null.</exception><exception cref="T:System.ArgumentException"><paramref name="dictionary"/> contains one or more duplicate keys.</exception>
        internal MenuEventDictionary( IDictionary<EventMenuKeyTuple, MethodInfo> dictionary, IEqualityComparer<EventMenuKeyTuple> comparer ) : base( dictionary, comparer ) {}

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.Dictionary`2"/> class with serialized data.
        /// </summary>
        /// <param name="info">A <see cref="T:System.Runtime.Serialization.SerializationInfo"/> object containing the information required to serialize the <see cref="T:System.Collections.Generic.Dictionary`2"/>.</param><param name="context">A <see cref="T:System.Runtime.Serialization.StreamingContext"/> structure containing the source and destination of the serialized stream associated with the <see cref="T:System.Collections.Generic.Dictionary`2"/>.</param>
        protected MenuEventDictionary( SerializationInfo info, StreamingContext context ) : base( info, context ) { }

        #endregion

        /// <summary>
        /// Indexador para facilitar acesso 
        /// </summary>
        /// <param name="aMenuType">Tipo/Id do menu.</param>
        /// <param name="aEventType">Tipo do evento do menu.</param>
        /// <param name="aBeforeAction">Indica se é um evento mapeado antes ou depois de ter sido tratado pelo SAP Business One.</param>
        /// <returns>Retorna um método quando encontrado. Do contrário, retorna nulo.</returns>
        public MethodInfo this[string aMenuType, BoEventTypes aEventType, bool aBeforeAction]
        {
            get
            {
                EventMenuKeyTuple lKey = Tuple.Create( aMenuType, aEventType, aBeforeAction );

                if ( ContainsKey( lKey ) )
                {
                    return base[lKey];
                }

                return null;
            }
        }

        /// <summary>
        /// Metodo auxiliar para a adição de itens na lista.
        /// </summary>
        /// <param name="aMenuType">Tipo/Id do menu.</param>
        /// <param name="aEventType">Tipo do evento do menu.</param>
        /// <param name="aBeforeAction">Indica se é um evento mapeado antes ou depois de ter sido tratado pelo SAP Business One.</param>
        /// <param name="aMethodInfo">Metodo que será invodado pela classe EventListener</param>
        public new void Add( string aMenuType, BoEventTypes aEventType, bool aBeforeAction, MethodInfo aMethodInfo )
        {
            EventMenuKeyTuple lKey = Tuple.Create( aMenuType, aEventType, aBeforeAction );

            base.Add( lKey, aMethodInfo );
        }
    }
}